package BankAccount;

import java.util.ArrayList;
import java.lang.StringBuilder;
import java.util.Random;
import java.util.Scanner;

public class Bank {
    private ArrayList<BankAccount> bArr = new ArrayList<>();

    public BankAccount getAccount(int index) {
        return this.bArr.get(index);
    }

//    public BankAccount[] getAccounts() {return bArr.;}

    /**
     * A method to print the information of all the bank accounts that is stored in the bank object.
     */
    public void showAccounts() {
        for (int i = 0; i < this.bArr.size(); i++) {
            System.out.println(this.bArr.get(i));
        }
    }

    public void opening(String accNumber, String accName) {
        bArr.add(new BankAccount(accNumber, accName));
    }

    public void opening(String accNumber, String accName, double balance) {
        bArr.add(new BankAccount(accNumber, accName, balance));
    }

    public void opening(String accName) {
        bArr.add(new BankAccount(auto_AccNumber_Producer(), accName));
    }

    /**
     * A method that will open a new bank account, including the normal one and a current account
     * @param accName The bank account name of the new bank account
     * @param balance The initial balance in the bank account.
     *                Current account must have some original balance.
     * @param accType A number that determine which kind of account to be created.
     */
    public void opening(String accName, double balance, int accType) {
        if (accType == 0) bArr.add(new BankAccount(auto_AccNumber_Producer(), accName, balance));
        if (accType == 1) bArr.add(new CurrentAccount(auto_AccNumber_Producer(), accName, balance));
    }

    public void closing(String accNumber, String accName) {
        for (int i = 0; i < bArr.size(); i++) {
            if (bArr.get(i).equals(accNumber, accName)) {
                Random r = new Random();
                Scanner sc = new Scanner(System.in);
                int check, input, count = 0;
                do {
                    check = r.nextInt(9999);
                    System.out.println("CAPTCHA: " + check);
                    System.out.println("Please enter captcha: ");
                    input = sc.nextInt();
                    if (check == input) {
                        System.out.println("Account has been removed.\n" + bArr.remove(i));
                        System.out.println("-------------------------------------------------------------------\n\n");
                        sc.close();
                        return;
                    } else count++;
                } while (count < 3);
                System.out.println("Closing operation failed. Suspend...");
                sc.close();
                return;
            }
        }
        System.out.println("Account not found. Suspend...");
    }

    public void closing(BankAccount bk) {
        for (int i = 0; i < bArr.size(); i++) {
            if (bArr.get(i).equals(bk)) {
                Random r = new Random();
                Scanner sc = new Scanner(System.in);
                int check, input, count = 0;
                do {
                    check = r.nextInt(1000, 9999);
                    System.out.println("CAPTCHA: " + check);
                    System.out.println("Please enter captcha: ");
                    input = sc.nextInt();
                    if (check == input) {
                        System.out.println("Account has been removed.\n" + bArr.remove(i));
                        System.out.println("-------------------------------------------------------------------\n\n");
                        sc.close();
                        return;
                    } else count++;
                } while (count < 3);
                System.out.println("Closing operation failed. Suspend...");
                sc.close();
                return;
            }
        }
        System.out.println("Account not found. Suspend...");
    }

    public void update() {
        for (int i = 0; i < bArr.size(); i++) {
            if (bArr.get(i).getClass().equals(new CurrentAccount().getClass())) {
                sendMessages(0, bArr.get(i));
            }
        }
    }

    /**
     * A method to produce bank accounts' code automatically.
     * @return A string that records the bank account's number.
     */
    public String auto_AccNumber_Producer() {
        StringBuilder sb = new StringBuilder();
        sb.append(bArr.size());
        while (sb.length() < 8) {
            sb.append(0);
        }
        return sb.reverse().toString();
    }

    /**
     * Send a certain kind of messages to a specified bank account object.
     * @param type A number to determine which kind of message will be sent.
     * @param bkAcc The bank account object to be sent messages.
     */
    public void sendMessages(int type, BankAccount bkAcc) {
        String message = null;
        switch (type) {
            case 0:
                message = "You're in overdraft " + bkAcc.getBalance();
                break;
            default:
                break;
        }
        if (!message.isBlank()) bkAcc.receiveMessage(message);
    }
}
